﻿using AutoUI;
using Mapster;
using MESPro.Controls;
using MESPro.DBManager;
using MESPro.Models;
using RM.Controls;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;
using MESPro.Global;
using System.Runtime.ConstrainedExecution;
using SqlSugar;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;
using MESPro.Models.FunctionType;
using System.Reflection.Emit;

namespace MESPro.Views
{
    public partial class DesignerFrm : DockContent
    {

        #region Public Constructors

        public DesignerFrm()
        {
            InitializeComponent();
            DoubleBuffered = true;
        }

        #endregion Public Constructors

        #region 字段

        private Function? function;

        #endregion 字段

        //int ParentId = 0;

        #region 属性

        public Function? Function
        {
            get => function;
            set
            {
                function = value;
                this.Invoke(() => { 等到数据后刷新界面(); });
            }
        }

        #endregion 属性

        #region Public 方法

        /// <summary>
        /// 遍历容器中的控件并序列化到数据库中
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void SaveControlLayoutToDb(object sender, EventArgs e)
        {
            var dbcontroList = new List<DbControl>();
            //递归
            int treeid = 0;
            ControlToDbControl(this.TSContainer.ContentPanel, dbcontroList, 0, ref treeid);
            if (Function is not null)
            {
                Function.DbControlGs = dbcontroList;
                List<Function> list = new List<Function>() { Function };
                var res = DbContext.Db
                      .UpdateNav(list)
                      .Include(it => it.DbControlGs)
                      .ExecuteCommand();
                MainServerFrm.RMShowMsg?.Invoke(res ? $"{function.DisName}保存界面成功" : $"{function.DisName}保存界面失败", Enums.MsgLevel.Trace);
            }
            else
            {
                MainServerFrm.RMShowMsg?.Invoke($"{function.DisName}保存界面失败:Function为空", Enums.MsgLevel.Trace);
            }


        }

        #endregion Public 方法

        #region Protected 方法

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            // e.Graphics.DrawLine(Pens.Red, 0, 0, 100, 100);
        }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            //base.OnPaint();
        }

        #endregion Protected 方法

        #region Private 方法

        /// <summary>
        /// 将数据库中的数据变成一个个控件
        /// </summary>
        private void 等到数据后刷新界面()
        {
            var cons = DbContext.Db.Queryable<DbControl>()
                .Where(g => g.FunctionId == Function!.Id)
                .Select(it => it.TreeCode).ToList().Cast<object>().ToArray();
            var tree = DbContext.Db.Queryable<DbControl>()
                .Where(g => g.FunctionId == Function!.Id)
                .ToTree(it => it.Child, it => it.ParentId, 0);
            //this.TSContainer.TopToolStripPanel.SuspendLayout();
            //this.TSContainer.SuspendLayout();
            //this.toolStrip1.SuspendLayout();
            //this.SuspendLayout();
            DbControlToControl(this.TSContainer.ContentPanel, tree);

            //this.TSContainer.TopToolStripPanel.ResumeLayout(false);
            //this.TSContainer.TopToolStripPanel.PerformLayout();
            //this.TSContainer.ResumeLayout(false);
            //this.TSContainer.PerformLayout();
            //this.toolStrip1.ResumeLayout(false);
            //this.toolStrip1.PerformLayout();
            //this.ResumeLayout(false);
        }



        /// <summary>
        /// 递归数据库控件树,生成实际控件
        /// </summary>
        /// <param name="Panel"></param>
        /// <param name="child"></param>
        private void DbControlToControl(Control Panel, List<DbControl> child)
        {
            // Panel.SuspendLayout();
            //ufo 添加新控件 设计时
            foreach (var item in child)
            {
                if (item.Style.FullName == typeof(RMPanel).FullName)
                {
                    var control = DBControlToControl<RMPanel>(Panel, item);
                    if (item.Child != null)
                    {
                        DbControlToControl(control, item.Child);
                    }
                }
                else if (item.Style.FullName == typeof(RMGroupBox).FullName)
                {
                    var control = DBControlToControl<RMGroupBox>(Panel, item);
                    if (item.Child != null)
                    {
                        DbControlToControl(control, item.Child);
                    }
                }
                else if (item.Style.FullName == typeof(RMDateTimePicker).FullName)
                {
                    var control = DBControlToControl<RMDateTimePicker>(Panel, item);

                    control.MouseDown += (s, e) =>
                    {
                        MainServerFrm.RMControlClick?.Invoke(s);
                    };

                    if (item.Child != null)
                    {
                        DbControlToControl(control, item.Child);
                    }
                }
                else if (item.Style.FullName == typeof(RMTabcontrol).FullName)
                {
                    var control = DBControlToControl<RMTabcontrol>(Panel, item);
                    if (item.Child != null)
                    {
                        DbControlToControl(control, item.Child);
                    }
                }
                else if (item.Style.FullName == typeof(RMButton).FullName)
                {
                    var control = DBControlToControl<RMButton>(Panel, item);
                    if (item.Child != null)
                    {
                        DbControlToControl(control, item.Child);
                    }
                }
                else if (item.Style.FullName == typeof(RMCheckBox).FullName)
                {
                    var control = DBControlToControl<RMCheckBox>(Panel, item);
                    if (item.Child != null)
                    {
                        DbControlToControl(control, item.Child);
                    }
                }
                else if (item.Style.FullName == typeof(RMRadioButton).FullName)
                {
                    var control = DBControlToControl<RMRadioButton>(Panel, item);
                    if (item.Child != null)
                    {
                        DbControlToControl(control, item.Child);
                    }
                }
                else if (item.Style.FullName == typeof(RMTextBox).FullName)
                {
                    var control = DBControlToControl<RMTextBox>(Panel, item);
                    if (item.Child != null)
                    {
                        DbControlToControl(control, item.Child);
                    }
                }
                else if (item.Style.FullName == typeof(RMLabel).FullName)
                {
                    var control = DBControlToControl<RMLabel>(Panel, item);
                    if (item.Child != null)
                    {
                        DbControlToControl(control, item.Child);
                    }
                }
                else if (item.Style.FullName == typeof(RMComboBox).FullName)
                {
                    var control = DBControlToControl<RMComboBox>(Panel, item);

                    //if (item.Child != null)
                    //{
                    //    DbControlToControl(control, item.Child);
                    //}
                }
                else if (item.Style.FullName == typeof(RMPdf).FullName)
                {
                    var control = DBControlToControl<RMPdf>(Panel, item);
                    if (item.Child != null)
                    {
                        DbControlToControl(control, item.Child);
                    }
                }
                else if (item.Style.FullName == typeof(RMPictureBox).FullName)
                {
                    var control = DBControlToControl<RMPictureBox>(Panel, item);
                    if (item.Child != null)
                    {
                        DbControlToControl(control, item.Child);
                    }
                }
                else if (item.Style.FullName == typeof(RMFlowLayoutPanel).FullName)
                {
                    var control = DBControlToControl<RMFlowLayoutPanel>(Panel, item);
                    if (item.Child != null)
                    {
                        DbControlToControl(control, item.Child);
                    }
                }
                else if (item.Style.FullName == typeof(RMDataGridView).FullName)
                {
                    var control = DBControlToControl<RMDataGridView>(Panel, item);
                    if (item.Child != null)
                    {
                        DbControlToControl(control, item.Child);
                    }
                }
                else if (item.Style.FullName == typeof(RMLabelTextBox).FullName)
                {
                    var control = DBControlToControl<RMLabelTextBox>(Panel, item);
                    if (item.Child != null)
                    {
                        DbControlToControl(control, item.Child);
                    }
                }

            }

        }
        /// <summary>
        /// 根据dbstyle生成一个控件,并放到容器中
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="page"></param>
        /// <param name="dbcontrol"></param>
        T DBControlToControl<T>(Control page, DbControl dbcontrol) where T : Control, new()
        {
            T control = new T();

            var ss = dbcontrol.Style.Adapt(control);//将style的属性赋值给btn

            dbcontrol.Style.Adapt(control);
            if (control is ITitleControl title)
            {
                title.DesignerInit();
            }
            //ufo 添加新控件 设计时
            if (control is RMComboBox cbx)
            {
                cbx.DataSource = null;
            }
            else if (control is RMLabelTextBox lt)
            {
                lt.Title = dbcontrol.Style.DisLanguage.GetDisplayName();
            }
            else if (control is RMTextBox t)
            {

            }
            else
            {
                control.Text = dbcontrol.Style.DisLanguage.GetDisplayName();
            }


            control.Click += (s, e) =>
            {

                MainServerFrm.RMControlClick?.Invoke(s);

            };
            //control.LocationChanged += (s, e) =>
            //{
            //    this.TSContainer.ContentPanel.Invalidate();
            //    var g = this.TSContainer.ContentPanel.CreateGraphics();
            //    var p = Control.MousePosition;
            //    var p2 = this.TSContainer.ContentPanel.PointToClient(p);
            //    g.DrawLine(Pens.Red, p2.X, p2.Y + 200, p2.X, p2.Y - 200);

            //    //this.TSContainer.ContentPanel.Invalidate();
            //};
            page.Controls.Add(control);
            control.AddMove();
            return control;
        }
        /// <summary>
        /// ufo 添加控件递归容器中所有控件,生成控件结构数据,用于保存到数据库
        /// </summary>
        /// <param name="panel"></param>
        /// <param name="dbcontroList"></param>
        /// <param name="pid"></param>
        /// <param name="treeid"></param>
        private void ControlToDbControl(Control panel, List<DbControl> dbcontroList, int pid, ref int treeid)
        {
            foreach (Control item2 in panel.Controls)
            {
                var style = item2.Adapt<Style>();//提取item2的属性
                if (item2 is RMComboBox cbx)
                {
                    style.DataSource = cbx.Items;//以后优化成Cfg
                }
                style.FullName = item2.GetType().FullName;
                DbControl db = new DbControl();
                db.Style = style;
                db.ParentId = pid;
                treeid = treeid + 1;
                db.TreeCode = treeid;
                dbcontroList.Add(db);
                if (item2.HasChildren
                    && (item2 is not RMLabelTextBox) && (item2 is not RMDataGridView)
                    )
                {
                    var xx = item2.Controls.Count;
                    ControlToDbControl(item2, dbcontroList, treeid, ref treeid);
                }
            }
        }

        private void TSContainer_ContentPanel_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Move;
            Debug.Write("拖动到工作区\r\n");

        }

        private void TSContainer_ContentPanel_DragDrop(object sender, DragEventArgs e)
        {
            var data = (e.Data.GetData(typeof(ListViewItem))) as ListViewItem;
            var point = this.TSContainer.ContentPanel.PointToClient(new Point(e.X, e.Y));
            if (data?.Tag is Type ty)
            {
                var con = (Control)ty.Assembly.CreateInstance(ty.FullName);
                con.Location = point;
                //ufo 添加新控件 设计时 拖拽
                if (con is ITitleControl title)
                {
                    title.DesignerInit();
                }
                if (con is RMDataGridView dgv)
                {
                    dgv.Name = "dgv";
                    dgv.DesignerInit();
                }
                else
                {
                    con.Name = Guid.NewGuid().ToString();
                }

                if (con is RMButton || con is RMCheckBox || con is RMRadioButton || con is RMGroupBox)
                {
                    con.Text = ty.Name.Substring(2);
                }
                if (con is RMDateTimePicker dtp)
                {
                    dtp.MouseDown += (s, e) =>
                    {
                        MainServerFrm.RMControlClick?.Invoke(s);
                    };
                }
                con.Click += (s, e) =>
                {
                    MainServerFrm.RMControlClick?.Invoke(s);
                };
                this.TSContainer.ContentPanel.Controls.Add(con);
                con.AddMove();
            }


        }

        private void TSContainer_ContentPanel_DragOver(object sender, DragEventArgs e)
        {
            //将对象拖 过 控件边界,yi zhi chu fa
            // Console.WriteLine("将对象拖 过 控件边界");
            this.TSContainer.ContentPanel.Invalidate();
            Debug.Write($"将对象拖 过 控件边界:{sender.GetType().FullName}\r\n");
        }

        private void TSContainer_ContentPanel_DragLeave(object sender, EventArgs e)
        {
            //将对象拖 出 控件边界
            Debug.Write("将对象拖 出 控件边界\r\n");
        }

        private void TSContainer_ContentPanel_QueryContinueDrag(object sender, QueryContinueDragEventArgs e)
        {
            Debug.Write("是否允许继续\r\n");

        }
        /// <summary>
        /// 遍历所有打开的窗口,然后生成DB界面,保存,后续需要提取通用方法出来
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripLabel2_Click(object sender, EventArgs e)
        {
            MainServerFrm.RMShowBar?.Invoke(0, false);
            foreach (var item in MainServerFrm.DesignerList)
            {
                var inter = 100 / MainServerFrm.DesignerList.Count;
                var dbcontroList = new List<DbControl>();
                //递归
                int treeid = 0;
                ControlToDbControl(item.Value.TSContainer.ContentPanel, dbcontroList, 0, ref treeid);

                item.Value.Function!.DbControlGs = dbcontroList;
                List<Function> list = new List<Function>() { item.Value.Function };
                var res = DbContext.Db
                      .UpdateNav(list)
                      .Include(it => it.DbControlGs)
                      .ExecuteCommand();
                MainServerFrm.RMShowMsg?.Invoke(res ? "保存界面成功" : "保存界面失败", Enums.MsgLevel.Trace);
                if (res)
                {
                    MainServerFrm.RMShowBar?.Invoke(inter, true);
                }

            }
        }
        private void 根据存储过程自动生成页面(object sender, EventArgs e)
        {
            return;
            ShowStoreProcedureLIst frm = new();
            frm.ShowDialog();
            var stname = frm.StoreProcedureName;
            var xxx = SqlHelperParameterCache.GetSpParameterSet(DbContext.conString, stname);
            TSContainer.ContentPanel.Controls.Clear();
            // int top = 0;
            Point point = new Point();
            //RMFlowLayoutPanel panel = new RMFlowLayoutPanel();
            // panel.Dock = DockStyle.Fill;
            foreach (var item in xxx)
            {
                if (item.ParameterName == "@Id" || item.ParameterName == "@rmsg" || item.ParameterName == "@DialogResult")
                {
                    continue;
                }
                if (item.SqlDbType == SqlDbType.Bit)
                {
                    RMCheckBox ctr = new RMCheckBox();
                    ctr.Location = point;
                    point.X = point.X + ctr.Width;
                    ctr.Click += (s, e) =>
                    {
                        MainServerFrm.RMControlClick?.Invoke(s);
                    };
                    this.TSContainer.ContentPanel.Controls.Add(ctr);
                    //point.Y = point.Y + rMCheckBox.Height;
                }
                else
                {
                    RMLabelTextBox ctr = new RMLabelTextBox();
                    ctr.Title = item.ParameterName;
                    ctr.Name = item.ParameterName.Substring(1);
                    ctr.Location = point;
                    point.X = point.X + ctr.Width;
                    ctr.Click += (s, e) =>
                    {
                        MainServerFrm.RMControlClick?.Invoke(s);
                    };
                    this.TSContainer.ContentPanel.Controls.Add(ctr);
                    ctr.AddMove();
                    //point.Y = point.Y + rMCheckBox.Height;
                }

                //panel.Controls.Add(textBox);

            }
            //this.TSContainer.ContentPanel.Controls.Add(panel);
        }

        private void DesignerFrm_Click(object sender, EventArgs e)
        {
            ;
        }

        private void DesignerFrm_Activated(object sender, EventArgs e)
        {
            ;
        }

        private void DesignerFrm_MdiChildActivate(object sender, EventArgs e)
        {
            ;
        }

        private void DesignerFrm_DockStateChanged(object sender, EventArgs e)
        {
            ;
        }

        private void DesignerFrm_MouseDown(object sender, MouseEventArgs e)
        {
            ;
        }

        private void TSContainer_ContentPanel_MouseMove(object sender, MouseEventArgs e)
        {
            //  if (e.)
            //  {
            // MouseButtons m =  Control.MouseButtons;
            //   if (m== MouseButtons.Left)
            //   {
            //  this.TSContainer.ContentPanel.Invalidate();
            // }
            // }
        }

        private void TSContainer_ContentPanel_Paint(object sender, PaintEventArgs e)
        {

            //var p=Control.MousePosition;
            //var p2=  this.TSContainer.ContentPanel.PointToClient(p);
            //e.Graphics.DrawLine(Pens.Red, p2.X, p2.Y+200, p2.X, p2.Y-200);
        }

        private void TSContainer_ContentPanel_MouseUp(object sender, MouseEventArgs e)
        {

        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            AutoBuildCRUDAndView frm = new AutoBuildCRUDAndView();
            frm.ShowDialog();
            BuildCRUDAndView(frm.TabName, frm.Columns);
        }
        /// <summary>
        /// ufo 自动生成crud
        /// </summary>
        /// <param name="tabName"></param>
        /// <param name="infos"></param>
        private void BuildCRUDAndView(string tabName, List<DbColumnInfo> infos)
        {
            StringBuilder INSERT = new StringBuilder();
            StringBuilder DELETE = new StringBuilder();
            StringBuilder UPDATE = new StringBuilder();
            StringBuilder SELECT = new StringBuilder();

            StringBuilder prams = new StringBuilder();//入口参数
            StringBuilder insert_fild = new StringBuilder();//插入字段
            StringBuilder insert_val = new StringBuilder();//插入参数
            StringBuilder update_pval = new StringBuilder();//更新字段和参数
            //ufo 插入固定参数
            prams.Append("  @rmsg NVARCHAR(1000)='' OUTPUT,--返回消息\r\n  @DialogResult NVARCHAR(20)='' ,--执行存储过程前选择的参数\r\n  -----------------以上为固定参数:后续增加机器名,ip,操作人等----\r\n");
            //处理infos
            foreach (DbColumnInfo info in infos)
            {
                //1.生成入口参数
                if (info.DataType == "int" || info.DataType == "datetime")
                {   //int 等没有长度
                    prams.Append($"@{info.DbColumnName} {info.DataType},\r\n");
                }
                else
                {
                    prams.Append($"@{info.DbColumnName} {info.DataType}({info.Length})='',\r\n");
                }
                //2.生成插入 字段和字段值
                if (!info.IsPrimarykey)
                {
                    insert_fild.Append($"{info.DbColumnName},\r\n");
                    insert_val.Append($"@{info.DbColumnName},\r\n");
                }
                else
                {

                }
                //生成更新字段
                if (!info.IsPrimarykey)
                {
                    update_pval.Append($"{info.DbColumnName}=@{info.DbColumnName},\r\n");
                }
            }

            INSERT.Append($"CREATE OR ALTER PROCEDURE {tabName}_INSERT\r\n");
            DELETE.Append($"CREATE OR ALTER PROCEDURE {tabName}_DELETE\r\n");
            UPDATE.Append($"CREATE OR ALTER PROCEDURE {tabName}_UPDATE\r\n");
            SELECT.Append($"CREATE OR ALTER PROCEDURE {tabName}_SELECT\r\n");
            //添加3个固定的参数
            prams.Remove(prams.Length - 3, 1);
            insert_fild.Remove(insert_fild.Length - 3, 1);
            insert_val.Remove(insert_val.Length - 3, 1);
            update_pval.Remove(update_pval.Length - 3, 1);

            prams.Append("AS \r\nBEGIN \r\nSET NOCOUNT ON;\r\n");
            prams.Append("\r\n--具体的内容\r\n");

            INSERT.Append(prams);
            DELETE.Append(prams);
            UPDATE.Append(prams);
            SELECT.Append(prams);

            INSERT.Append($"  INSERT INTO {tabName}\r\n    (");
            INSERT.Append(insert_fild);
            INSERT.Append(" )\r\n    VALUES\r\n    (");
            INSERT.Append(insert_val);
            INSERT.Append(" );");

            DELETE.Append($"DELETE FROM {tabName}\r\n    WHERE Id = @Id;\r\n");

            UPDATE.Append($" UPDATE {tabName}\r\n    SET \r\n");
            UPDATE.Append(update_pval);
            UPDATE.Append(" WHERE Id = @Id;");

            SELECT.Append($"SELECT * FROM {tabName};\r\n");

            //具体内容
            INSERT.Append("\r\n--具体的内容\r\nEND;");
            DELETE.Append("\r\n--具体的内容\r\nEND;");
            UPDATE.Append("\r\n--具体的内容\r\nEND;");
            SELECT.Append("\r\n--具体的内容\r\nEND;");
            var sql_insert = INSERT.ToString();
            var sql_delete = DELETE.ToString();
            var sql_update = UPDATE.ToString();
            var sql_select = SELECT.ToString();

            var res1 = DbContext.Db.Ado.ExecuteCommand(sql_insert);
            var res2 = DbContext.Db.Ado.ExecuteCommand(sql_delete);
            var res3 = DbContext.Db.Ado.ExecuteCommand(sql_update);
            var res4 = DbContext.Db.Ado.ExecuteCommand(sql_select);

            this.TSContainer.ContentPanel.Controls.Clear();
            RMDataGridView dgv = new RMDataGridView();
            dgv.MouseDown += (s, e) =>
            {
                MainServerFrm.RMControlClick?.Invoke(s);
            };
            dgv.Name = "dgv";



            RMPanel panel = new RMPanel();

            TSContainer.ContentPanel.Controls.Add(panel);
            TSContainer.ContentPanel.Controls.Add(dgv);
            panel.Dock = DockStyle.Fill;
            dgv.Dock = DockStyle.Left;

            Point point = new Point();
            foreach (var item in infos)
            {
                if (item.IsPrimarykey)
                {
                    continue;
                }
                else if (item.DataType == "datetime")
                {
                    RMDateTimePicker con = new RMDateTimePicker();
                    con.Name = item.DbColumnName;
                    if (point.X + con.Width > panel.Width)
                    {
                        point.X = 0;
                        point.Y = point.Y + 50;
                        con.Location = point;
                        point.X = point.X + con.Width;
                    }
                    else
                    {
                        con.Location = point;
                        point.X = point.X + con.Width;
                    }
                    con.MouseDown += (s, e) =>
                    {
                       // MainServerFrm.RMControlClick?.Invoke(s);
                    };
                    panel.Controls.Add(con);
                    con.AddMove();
                    if (con is ITitleControl title)
                    {
                        title.DesignerInit();
                    }

                }
                else
                {
                    RMLabelTextBox con = new RMLabelTextBox();
                    con.Title = item.ColumnDescription;
                    con.Name = item.DbColumnName;

                    if (point.X + con.Width > panel.Width)
                    {
                        point.X = 0;
                        point.Y = point.Y + 50;
                        con.Location = point;
                        point.X = point.X + con.Width;
                    }
                    else
                    {
                        con.Location = point;
                        point.X = point.X + con.Width;
                    }
                    con.Click += (s, e) =>
                    {
                        MainServerFrm.RMControlClick?.Invoke(s);
                    };
                    panel.Controls.Add(con);
                    con.AddMove();
                    if (con is ITitleControl title)
                    {
                        title.DesignerInit();
                    }
                }
            }
            if (this.function != null)
            {
                string ps = "";
                infos.Select(x => x.DbColumnName)
                     .ToList()
                     .ForEach(x => ps = ps + "@" + x + ",");
                function.InsertStoredProcedure = new StoreProInfo()
                {
                    StoreName = $"{tabName}_INSERT",
                    StoreParms = ps
                };
                function.DeleteStoredProcedure = new StoreProInfo()
                {
                    StoreName = $"{tabName}_DELETE",
                    StoreParms = ps
                };
                function.UpdateStoredProcedure = new StoreProInfo()
                {
                    StoreName = $"{tabName}_UPDATE",
                    StoreParms = ps
                };
                function.QueryStoredProcedure = new StoreProInfo()
                {
                    StoreName = $"{tabName}_SELECT",
                    StoreParms = ps
                };
            }

        }

        #endregion Private 方法
    }
}
